package org.study.ratelimiter;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.study.ratelimiter.annotation.DoRateLimiter;
import org.study.ratelimiter.value.IValveService;
import org.study.ratelimiter.value.impl.RateLimiterValve;

import java.lang.reflect.Method;

/**
 * 定义切面
 */
@Aspect
@Component
public class DoRateLimiterPoint {
    // 定义切点，这里是定义到注解上，一般有时候会定义到某个包路径下
    @Pointcut("@annotation(org.study.ratelimiter.annotation.DoRateLimiter)")
    public void aopPoint() {
    }

    @Around("aopPoint() && @annotation(doRateLimiter)")
    public Object doRouter(ProceedingJoinPoint jp, DoRateLimiter doRateLimiter) throws Throwable {
        IValveService valveService = new RateLimiterValve();
        return valveService.access(jp, getMethod(jp), doRateLimiter, jp.getArgs());
    }
    public Method getMethod(ProceedingJoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());

    }
}
